import random
from threading import Thread
from database import ipredis, sql_db
from utils.req_utils import get_session
from models.proxies import ProxyModel
from logger import logger


class ProxyLogic:
    """
    代理相关的逻辑
    """

    def __init__(self):
        self.redis_key = 'proxies'
        self.init_score = 10
        self.min_score = self.init_score - 1
        self.max_score = self.init_score
        self.need_num = self.init_score - 5
        self.session = get_session()

    def get_proxies_from_zhima(self, num):
        """从芝麻代码中获取IP"""
        # 直连IP
        url = f'http://webapi.http.zhimacangku.com/getip?num={num}&type=2&pro=&city=0&yys=0&port=1&time=1&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=2&regions='
        resp = self.session.get(url)
        resp = resp.json()
        proxies = []
        if resp.get('code', 0) == 0:
            data = resp.get('data', [])
            for d in data:
                ip = d.get('ip')
                port = d.get('port')
                proxies.append(f'{ip}:{port}')
        else:
            logger.error(f'请求芝麻代理失败, error: {resp}')
        return proxies

    def get_proxies(self):
        proxies = self.get_proxies_from_zhima(10)
        for proxy in proxies:
            self.add(proxy)
            ProxyModel.add_proxy(sql_db, proxy, "芝麻代理")
        return proxies

    def add(self, proxy):
        """添加代理"""
        if not ipredis.zscore(self.redis_key, proxy):
            # 添加IP，初始分数为10
            mapping = {proxy: self.init_score}
            return ipredis.zadd(self.redis_key, mapping)

    def count(self):
        """数量"""
        return ipredis.zcard(self.redis_key)

    def all(self):
        """获得所有代理"""
        return ipredis.zrangebyscore(self.redis_key, 0, 10)

    def random(self):
        """随机获得有效代理"""
        # 失败2次就不用了
        proxies = ipredis.zrangebyscore(self.redis_key, self.max_score, self.max_score)
        num = len(proxies)
        if num:
            if num < self.need_num:
                Thread(target=self.get_proxies).start()
        else:
            # 动态请求获取
            proxies = self.get_proxies()
        if len(proxies):
            return random.choice(proxies)
        else:
            return ''

    def delete(self, proxy):
        """从redis中删除"""
        result = ipredis.zrem(self.redis_key, proxy)
        return result

    def descrease(self, proxy):
        """减分"""
        score = ipredis.zscore(self.redis_key, proxy)
        if score and score > self.min_score:
            return ipredis.zincrby(self.redis_key, -1, proxy)
        else:
            # 分数低于最小值，删除代理
            ProxyModel.modify_proxy(sql_db, proxy, 0)
            return self.delete(proxy)
